/**
 * This software was produced for the U. S. Government
 * under Contract No. FA8721-09-C-0002, and is
 * subject to the Rights in Noncommercial Computer Software
 * and Noncommercial Computer Software Documentation Clause
 * (DFARS) 252.227-7014 (JUN 1995)
 * 
 * (c) 2009 The MITRE Corporation. All Rights Reserved.
 *
 * SPMIF to OPNET Translator
 * Author: ewalters
 * Created: 3:32:14 PM, Aug 9, 2007
 * MITRE Corporation
 */
package com.mitre.spmif2opnet.analysis.ast;

import java.util.Collection;

import com.mitre.spmif2opnet.VisitorContext;
import com.mitre.spmif2opnet.analysis.Identifier;

/**
 * Repetition Node, i.e. simple node with repetition count
 */
public class RepNode extends Node implements Visitee {
	/**
	 * Repetition factor
	 */
	private double _factor;
	/**
	 * The node to repeat
	 */
	private Node   _child;
	
	/**
	 * Default constructor
	 * @param name node name
	 * @param id   node id
	 * @param factor node factor
	 * @param child  child node
	 */
	public RepNode(String name, String id, double factor, Node child) {
		super(name, id, 1.0);
		_factor = factor;
		_child = child;
	}
	
	/**
	 * Visitor accepter
	 */
	public <T> VisitorContext<T> accept(NodeVisitor<T> v, VisitorContext<T> c) {
		return v.visit(this, c);
	}

	/**
	 * Factor accessor
	 * @return the factor as an int (how do we fractionally repeat?)
	 */
	public int getFactor() {
		return (new Double(Math.floor(_factor))).intValue();
	}
	
	/**
	 * Child accessor
	 * @return the child
	 */
	public Node getChild() {
		return _child;
	}
	
	/**
	 * What resources are associated with the node?
	 * @return the resource names
	 */
	public Collection<String> getResources() {
		Collection<String> res = super.getResources();
		if (res.isEmpty()) {
			res = _child.getResources();
		}
		return res;
	}
	
	/**
	 * Get the services that correspond to the resource
	 * Use the resources of the child node (if ours not present)
	 * @param res_name the resource name
	 * @return the units
	 */
	public double getResourceService(String res_name) {
		Double service = null;
		if (_resources.isEmpty()) {
			service = new Double(_child.getResourceService(res_name));
		} else {
			service = _resources.get(res_name);
		}
		return (service == null) ? 0.0 : service.doubleValue();
	}
	
	/**
	 * Copy function
	 * @return the copy
	 */
	public RepNode copy() {
		RepNode new_node = new RepNode(this.getId(), Identifier.newNodeId(this.getId()), 
				_factor, _child.copy());
		new_node.copyResources(this);
		return new_node;
	}

}
